package model

import (
	"admin/contrib/session"
	ryrpc "admin/rpc"
	"bytes"
	"common/helper"
	myredis "common/redis"
	"database/sql"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/360EntSecGroup-Skylar/excelize"
	g "github.com/doug-martin/goqu/v9"
	"github.com/valyala/fasthttp"
	"io"
	"math"
	"math/rand"
	"net/http"
	"strconv"
	"strings"
	"time"
)

type Loginuser struct {
	Admin     string
	Operator  string
	Businsess string
}

// 获取登录账号类型
func GetLoginUser(ctx *fasthttp.RequestCtx) Loginuser {
	data := Loginuser{}
	loginuser := session.AdminGet(ctx)
	if loginuser["loginuser"] == "admin" {
		data.Admin = loginuser["id"]
	}
	if loginuser["loginuser"] == "merchant" {
		data.Operator = loginuser["id"]
	}
	if loginuser["loginuser"] == "business" {
		data.Businsess = loginuser["id"]
	}
	return data
}

// 统计数据修正
func FixGameDaily(from string, to string) bool {
	t1, _ := time.ParseInLocation("2006-01-02", from, time.Local)
	fromTimestamp := t1.Unix()

	t2, _ := time.ParseInLocation("2006-01-02", to, time.Local)
	toTimestamp := t2.Unix()

	for {
		if fromTimestamp > toTimestamp {
			break
		}
		where := " a.cash_type in(" + strconv.Itoa(helper.TransactionBet) + "," + strconv.Itoa(helper.TransactionPayout) + ")"
		timeStr := time.Unix(fromTimestamp, 0).Format("2006-01-02")
		data := []TblReportGameDaily{}
		st, err := time.ParseInLocation("2006-01-02", timeStr, loc)
		if err != nil {

		}
		StartTime := st.UnixMilli()
		StartTime2 := strconv.FormatInt(StartTime, 10)
		where += " and a.created_at>='" + StartTime2 + "'"
		EndTime := StartTime + 86400*1000
		EndTime2 := strconv.FormatInt(EndTime, 10)
		where += " and a.created_at<'" + EndTime2 + "'"

		query := "select b.operator_id,a.platform_id,ifnull(sum(case when cash_type=301 then 1 else 0 end),0) as game_round,ifnull(-sum(case when cash_type=301 then amount else 0 end),0) as running,ifnull(sum(case when cash_type=302 then amount+game_tax else 0 end),0) as game_winlost,ifnull(sum(case when cash_type=302 then game_tax else 0 end),0) as game_tax from tbl_balance_transaction  as a join tbl_member_base as b on b.uid=a.uid  where " + where + " group by b.operator_id,a.platform_id"

		err = meta.MerchantDB.Select(&data, query)
		for _, value := range data {
			value.CreatedAt = timeStr
			value.BusinessId = "0"
			query, _, _ = dialect.Insert("tbl_report_game_daily_copy").Rows(value).ToSQL()
			meta.MerchantDB.Exec(query)
		}

		query = "select b.operator_id,b.business_id,a.platform_id,ifnull(sum(case when cash_type=301 then 1 else 0 end),0) as game_round,ifnull(-sum(case when cash_type=301 then amount else 0 end),0) as running,ifnull(sum(case when cash_type=302 then amount+game_tax else 0 end),0) as game_winlost,ifnull(sum(case when cash_type=302 then game_tax else 0 end),0) as game_tax from tbl_balance_transaction  as a join tbl_member_base as b on b.uid=a.uid  where " + where + " and b.business_id>0 group by b.operator_id,b.business_id,a.platform_id"

		err = meta.MerchantDB.Select(&data, query)
		for _, value := range data {
			value.CreatedAt = timeStr
			query, _, _ = dialect.Insert("tbl_report_game_daily_copy").Rows(value).ToSQL()
			meta.MerchantDB.Exec(query)
		}

		fromTimestamp = fromTimestamp + 86400
	}
	return true
}

// 统计数据修正
func FixDailyData(from string, to string) bool {
	t1, _ := time.ParseInLocation("2006-01-02", from, time.Local)
	fromTimestamp := t1.Unix()

	t2, _ := time.ParseInLocation("2006-01-02", to, time.Local)
	toTimestamp := t2.Unix()

	for {
		if fromTimestamp > toTimestamp {
			break
		}
		timeStr := time.Unix(fromTimestamp, 0).Format("2006-01-02")

		StatisticalData(timeStr, fromTimestamp)
		fromTimestamp = fromTimestamp + 86400
	}
	return true
}

// 定时任务
func CronDailyData() {

	//业务逻辑，每五分钟执行，凌晨00：05之前 执行昨天的统计，00:05 之后执行今天的统计
	now := time.Now()

	nowTimestamp := now.Unix()
	lcTimestamp := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()).Unix()

	if (nowTimestamp - lcTimestamp) > 60*5 {
		//统计今天
		timeDate := time.Unix(nowTimestamp, 0).Format("2006-01-02")
		StatisticalData(timeDate, lcTimestamp)
	} else {
		//统计昨天
		yes := now.AddDate(0, 0, -1)
		yesTimestamp := time.Date(yes.Year(), yes.Month(), yes.Day(), 0, 0, 0, 0, yes.Location()).Unix()
		timeDate := time.Unix(yesTimestamp, 0).Format("2006-01-02")
		StatisticalData(timeDate, yesTimestamp)
	}
}

func StatisticalData(timeDate string, timestamp int64) {
	//业务员数据
	var businessList []TblBusinessInfo
	query := "select * from tbl_business_info"

	err := meta.MerchantDB.Select(&businessList, query)
	if err != nil && err != sql.ErrNoRows {
		return
	}
	if len(businessList) > 0 {
		for _, value := range businessList {
			goBusinessDailyData(value, timeDate, timestamp)
		}
	}
	//渠道数据
	var operatorList []TblOperatorInfo
	query = "select * from tbl_operator_info"
	err = meta.MerchantDB.Select(&operatorList, query)
	if err != nil && err != sql.ErrNoRows {
		return
	}
	if len(operatorList) > 0 {
		for _, value := range operatorList {
			goOperatorDailyData(value, timeDate, timestamp)
		}
	}
}

// 并发执行业务员数据统计
func goBusinessDailyData(value TblBusinessInfo, timeDate string, timestamp int64) {
	endTimestamp := timestamp + 86400
	businessId := value.Id
	businessData := TblReportDailyData{}
	query := "select * from tbl_report_daily where business_id=" + businessId + " and created_at='" + timeDate + "'"
	_ = meta.MerchantDB.Get(&businessData, query)

	field := "IFNULL(sum(a.deposit),0) deposit," +
		"IFNULL(sum(a.withdraw),0) withdraw," +
		"IFNULL(sum(a.running),0) running," +
		"IFNULL(sum(a.game_round),0) game_round," +
		"IFNULL(sum(a.game_tax),0) game_tax," +
		"IFNULL(sum(a.game_winlost),0) game_winlost," +
		"IFNULL(sum(a.proxy_invite_bonus),0) proxy_invite_bonus," +
		"IFNULL(sum(a.accu_deposit_bonus),0) accu_deposit_bonus," +
		"IFNULL(sum(a.accu_deposit_bonus),0) accu_deposit_bonus," +
		"IFNULL(sum(a.week_lost_return),0) week_lost_return," +
		"IFNULL(sum(a.week_bet_return),0) week_bet_return," +
		"IFNULL(sum(a.week_deposit_return),0) week_deposit_return," +
		"IFNULL(sum(a.week_commi_return),0) week_commi_return," +
		"IFNULL(sum(a.daily_bet_return),0) daily_bet_return," +
		"IFNULL(sum(a.app_download_bonus),0) app_download_bonus," +
		"IFNULL(sum(a.enable_first_deposit_to_parent),0) enable_first_deposit_to_parent," +
		"IFNULL(sum(a.enable_recharge_share),0) enable_recharge_share," +
		"COUNT(CASE WHEN game_round != 0 THEN 1 ELSE NULL END) active_user," +
		"IFNULL(sum(a.first_deposit),0) first_deposit"
	query = "select " + field + " from tbl_report_user_daily as a join tbl_member_base as b on a.uid=b.uid where a.created_at='" + timeDate + "' and b.business_id=" + businessId
	_ = meta.MerchantDB.Get(&businessData, query)
	//充值人数
	query = fmt.Sprintf("select count(1) from tbl_report_user_daily as a join tbl_member_base as b on a.uid=b.uid where a.deposit>0 and a.created_at='%s' and b.business_id=%s", timeDate, businessId)
	_ = meta.MerchantDB.Get(&businessData.DepositNum, query)
	//提现人数
	query = fmt.Sprintf("select count(1) from tbl_report_user_daily as a join tbl_member_base as b on a.uid=b.uid where a.withdraw>0 and a.created_at='%s' and  b.business_id=%s", timeDate, businessId)
	_ = meta.MerchantDB.Get(&businessData.WithdrawNum, query)
	//未充提款
	query = fmt.Sprintf("select IFNULL(sum(a.withdraw),0) from tbl_report_user_daily as a join tbl_member_base as b on a.uid=b.uid join tbl_member_accu as c on c.uid=a.uid  where c.deposit=0 and a.withdraw>0 and a.created_at='%s' and  b.business_id=%s", timeDate, businessId)
	_ = meta.MerchantDB.Get(&businessData.UndepositWithdraw, query)

	//首充人数
	query = fmt.Sprintf("select count(1) from tbl_report_user_daily as a join tbl_member_base as b on a.uid=b.uid where a.first_deposit>0 and a.created_at='%s' and  b.business_id=%s", timeDate, businessId)
	_ = meta.MerchantDB.Get(&businessData.FirstDepositNum, query)

	//有效人数
	query = fmt.Sprintf("select IFNULL(sum(valid_num),0) valid_num from tbl_report_proxy_daily as a join tbl_member_base as b on a.uid=b.uid where a.level=1 and a.created_at='%s' and b.business_id=%s", timeDate, businessId)
	_ = meta.MerchantDB.Get(&businessData.ValidNum, query)

	//新增玩家
	query = fmt.Sprintf("select count(1) from tbl_member_base where tester=1 and created_at>=%d and created_at<%d and business_id=%s", timestamp, endTimestamp, businessId)
	_ = meta.MerchantDB.Get(&businessData.NewUser, query)
	// 上分
	query = fmt.Sprintf("select IFNULL(SUM(amount), 0) from tbl_member_adjust as a join tbl_member_base as b on a.uid=b.uid where b.tester=1 and a.state=2 and adjust_mode=1 and a.apply_at>=%d and a.apply_at<%d and b.business_id=%s", timestamp, endTimestamp, businessId)

	_ = meta.MerchantDB.Get(&businessData.UpScore, query)
	//下分
	query = fmt.Sprintf("select IFNULL(SUM(amount), 0) from tbl_member_adjust as a join tbl_member_base as b on a.uid=b.uid where b.tester=1 and a.state=2 and adjust_mode=2 and a.apply_at>=%d and a.apply_at<%d and b.business_id=%s", timestamp, endTimestamp, businessId)
	_ = meta.MerchantDB.Get(&businessData.DownScore, query)

	if businessData.Id > 0 {
		//更新
		query, _, _ = dialect.Update("tbl_report_daily").Set(businessData).Where(g.Ex{"id": businessData.Id}).ToSQL()
		meta.MerchantDB.Exec(query)

	} else {
		businessData.BusinessId = businessId
		businessData.OperatorId = value.OperatorId
		businessData.CreatedAt = timeDate
		//先删，避免重复
		query, _, _ = dialect.Delete("tbl_report_daily").Where(g.Ex{
			"business_id": businessId,
			"operator_id": value.OperatorId,
			"created_at":  timeDate,
		}).ToSQL()
		meta.MerchantDB.Exec(query)
		//插入
		query, _, _ = dialect.Insert("tbl_report_daily").Rows(businessData).ToSQL()
		meta.MerchantDB.Exec(query)

	}
}

// 并发执行渠道数据统计
func goOperatorDailyData(value TblOperatorInfo, timeDate string, timestamp int64) {
	endTimestamp := timestamp + 86400
	operatorId := value.Id
	operatorData := TblReportDailyData{}
	query := "select * from tbl_report_daily where business_id=0 and operator_id=" + operatorId + " and created_at='" + timeDate + "'"
	_ = meta.MerchantDB.Get(&operatorData, query)

	field := "IFNULL(sum(a.deposit),0) deposit," +
		"IFNULL(sum(a.withdraw),0) withdraw," +
		"IFNULL(sum(a.running),0) running," +
		"IFNULL(sum(a.game_round),0) game_round," +
		"IFNULL(sum(a.game_tax),0) game_tax," +
		"IFNULL(sum(a.game_winlost),0) game_winlost," +
		"IFNULL(sum(a.proxy_invite_bonus),0) proxy_invite_bonus," +
		"IFNULL(sum(a.accu_deposit_bonus),0) accu_deposit_bonus," +
		"IFNULL(sum(a.accu_deposit_bonus),0) accu_deposit_bonus," +
		"IFNULL(sum(a.week_lost_return),0) week_lost_return," +
		"IFNULL(sum(a.week_bet_return),0) week_bet_return," +
		"IFNULL(sum(a.week_deposit_return),0) week_deposit_return," +
		"IFNULL(sum(a.week_commi_return),0) week_commi_return," +
		"IFNULL(sum(a.daily_bet_return),0) daily_bet_return," +
		"IFNULL(sum(a.app_download_bonus),0) app_download_bonus," +
		"IFNULL(sum(a.enable_first_deposit_to_parent),0) enable_first_deposit_to_parent," +
		"IFNULL(sum(a.enable_recharge_share),0) enable_recharge_share," +
		"COUNT(CASE WHEN game_round != 0 THEN 1 ELSE NULL END) active_user," +
		"IFNULL(sum(a.first_deposit),0) first_deposit"
	query = "select " + field + " from tbl_report_user_daily as a join tbl_member_base as b on a.uid=b.uid where a.created_at='" + timeDate + "' and b.operator_id=" + operatorId
	_ = meta.MerchantDB.Get(&operatorData, query)

	//充值人数
	query = fmt.Sprintf("select count(1) from tbl_report_user_daily as a join tbl_member_base as b on a.uid=b.uid where a.deposit>0 and a.created_at='%s'  and b.operator_id=%s", timeDate, operatorId)
	_ = meta.MerchantDB.Get(&operatorData.DepositNum, query)
	//提现人数
	query = fmt.Sprintf("select count(1) from tbl_report_user_daily as a join tbl_member_base as b on a.uid=b.uid where a.withdraw>0 and a.created_at='%s'  and b.operator_id=%s", timeDate, operatorId)
	_ = meta.MerchantDB.Get(&operatorData.WithdrawNum, query)

	//未充提款
	query = fmt.Sprintf("select IFNULL(sum(a.withdraw),0) from tbl_report_user_daily as a join tbl_member_base as b on a.uid=b.uid join tbl_member_accu as c on c.uid=a.uid  where c.deposit=0 and a.withdraw>0 and a.created_at='%s' and  b.operator_id=%s", timeDate, operatorId)
	_ = meta.MerchantDB.Get(&operatorData.UndepositWithdraw, query)

	//首充人数
	query = fmt.Sprintf("select count(1) from tbl_report_user_daily as a join tbl_member_base as b on a.uid=b.uid where a.first_deposit>0 and a.created_at='%s'  and b.operator_id=%s", timeDate, operatorId)
	_ = meta.MerchantDB.Get(&operatorData.FirstDepositNum, query)

	//团队人数 + 有效人数
	query = fmt.Sprintf("select IFNULL(sum(valid_num),0) valid_num from tbl_report_proxy_daily as a join tbl_member_base as b on a.uid=b.uid where a.level=1 and a.created_at='%s' and b.operator_id=%s", timeDate, operatorId)
	_ = meta.MerchantDB.Get(&operatorData.ValidNum, query)

	//新增玩家
	query = fmt.Sprintf("select count(1) from tbl_member_base where tester=1 and created_at>=%d and created_at<%d and operator_id=%s", timestamp, endTimestamp, operatorId)
	_ = meta.MerchantDB.Get(&operatorData.NewUser, query)
	// 上分
	query = fmt.Sprintf("select IFNULL(SUM(amount), 0) from tbl_member_adjust as a join tbl_member_base as b on a.uid=b.uid where b.tester=1 and a.state=2 and adjust_mode=1 and a.apply_at>=%d and a.apply_at<%d and b.operator_id=%s", timestamp, endTimestamp, operatorId)

	_ = meta.MerchantDB.Get(&operatorData.UpScore, query)
	//下分
	query = fmt.Sprintf("select IFNULL(SUM(amount), 0) from tbl_member_adjust as a join tbl_member_base as b on a.uid=b.uid where b.tester=1 and a.state=2 and adjust_mode=2 and a.apply_at>=%d and a.apply_at<%d and  b.operator_id=%s", timestamp, endTimestamp, operatorId)
	_ = meta.MerchantDB.Get(&operatorData.DownScore, query)
	if operatorData.Id > 0 {
		//更新
		query, _, _ = dialect.Update("tbl_report_daily").Set(operatorData).Where(g.Ex{"id": operatorData.Id}).ToSQL()
		meta.MerchantDB.Exec(query)
	} else {
		operatorData.BusinessId = "0"
		operatorData.OperatorId = operatorId
		operatorData.CreatedAt = timeDate
		//先删，避免重复
		query, _, _ = dialect.Delete("tbl_report_daily").Where(g.Ex{
			"business_id": "0",
			"operator_id": operatorId,
			"created_at":  timeDate,
		}).ToSQL()
		meta.MerchantDB.Exec(query)
		//插入
		query, _, _ = dialect.Insert("tbl_report_daily").Rows(operatorData).ToSQL()
		meta.MerchantDB.Exec(query)

	}
}

// 获取伞下全部业务员 以及自身 列表
func GetBusinessTeam(businessId string, businessIds string) string {
	data := []string{}
	query := "select id from tbl_business_info where parent_id in(" + businessId + ")"
	err := meta.MerchantDB.Select(&data, query)
	if err != nil && err != sql.ErrNoRows {
		return ""
	}

	if len(data) > 0 {
		newBusinessId := strings.Join(data, ",")
		businessIds += "," + newBusinessId
		return GetBusinessTeam(newBusinessId, businessIds)
	} else {
		return businessIds
	}
}

// 账变记录
func UpdateBalance(uid string, balance float64, changeType int, billNo string) (bool, error) {
	if balance == 0 {
		return false, errors.New(helper.AmountErr)
	}
	beforBalance := myredis.GetUserFieldFloat64(uid, "tbl_member_balance:brl")

	//扣钱，先扣，后插记录
	if balance < 0 {
		if (beforBalance + balance) < 0 {
			return false, errors.New(helper.LackOfBalance)
		}
		ret := myredis.AddUserFieldValueByFloat64(uid, "tbl_member_balance:brl", balance)
		if ret == false {
			helper.InfoLog("资金变动error：%s---%f---%f", uid, beforBalance, balance)
			return false, errors.New(helper.ServerErr)
		}
		trans := MemberTransaction{
			AfterAmount:  beforBalance + balance,
			Amount:       balance,
			BeforeAmount: beforBalance,
			BillNo:       billNo,
			CreatedAt:    time.Now().UnixMilli(),
			CashType:     changeType,
			UID:          uid,
			PlatformID:   "0",
		}
		//query, _, _ := dialect.Insert("tbl_balance_transaction").Rows(trans).ToSQL()
		//myredis.UpdateSqlFieldToRedis(query)
		data, _ := json.Marshal(trans)
		myredis.UpdateTransactionToRedis(data)
	}
	//加钱，先插记录，后加钱
	if balance > 0 {
		trans := MemberTransaction{
			AfterAmount:  beforBalance + balance,
			Amount:       balance,
			BeforeAmount: beforBalance,
			BillNo:       billNo,
			CreatedAt:    time.Now().UnixMilli(),
			CashType:     changeType,
			UID:          uid,
			GameTax:      0,
			PlatformID:   "0",
		}
		//query, _, _ := dialect.Insert("tbl_balance_transaction").Rows(trans).ToSQL()

		data, _ := json.Marshal(trans)
		myredis.UpdateTransactionToRedis(data)
		//myredis.UpdateSqlFieldToRedis(query)
		ret := myredis.AddUserFieldValueByFloat64(uid, "tbl_member_balance:brl", balance)
		if ret == false {
			helper.InfoLog("资金变动error：%s---%f---%f", uid, beforBalance, balance)
			return false, errors.New(helper.ServerErr)
		}
	}
	if changeType == helper.TransactionDepositHandle {
		myredis.AddUserFieldValueByFloat64(uid, "tbl_member_accu:deposit", balance)
		myredis.AddUserFieldValueByInt64(uid, "tbl_member_accu:deposit_times", 1)
	}
	afterBalance := myredis.GetUserFieldFloat64(uid, "tbl_member_balance:brl")
	helper.InfoLog("资金变动：%s---%f---%f---%f", uid, beforBalance, balance, afterBalance)
	myredis.ImmediateUpdateRole(uid)
	return true, nil
}

// 插入后台操作日志
func InsertOptLog(opttype int, opt_id int, name string, url string, param string, ip string) (bool, error) {

	data := g.Record{
		"type":   opttype,
		"name":   name,
		"url":    url,
		"param":  param,
		"opt_id": opt_id,
		"ip":     ip,
		"date":   time.Now().Format("2006-01-02 15:04:05"),
	}
	query, _, _ := dialect.Insert("tbl_background_log").Rows(data).ToSQL()
	_, err := meta.MerchantDB.Exec(query)
	if err != nil {
		//fmt.Println(err)
		return false, errors.New("数据库错误")
	}
	return true, nil
}

// 插入全部范文日志
func InsertAdminLog(opttype string, opt_id string, name string, url string, param string, ip string) (bool, error) {

	data := g.Record{
		"type":   opttype,
		"name":   name,
		"url":    url,
		"param":  param,
		"opt_id": opt_id,
		"ip":     ip,
		"date":   time.Now().Format("2006-01-02 15:04:05"),
	}
	query, _, _ := dialect.Insert("tbl_admin_log").Rows(data).ToSQL()
	_, err := meta.MerchantDB.Exec(query)
	if err != nil {
		//fmt.Println(err)
		return false, errors.New("数据库错误")
	}
	return true, nil
}

// 玩家权限验证
func UserAuthCheck(userInfo ryrpc.TblMemberBase, ctx *fasthttp.RequestCtx) (bool, error) {
	loginUser := GetLoginUser(ctx)
	if loginUser.Operator != "" {
		if userInfo.OperatorId != loginUser.Operator {
			return false, errors.New("权限不足")
		}
	} else if loginUser.Businsess != "" {
		if userInfo.BusinessId != loginUser.Businsess {
			return false, errors.New("权限不足")
		}
	}
	return true, nil
}
func InsertLog(name string, ctx *fasthttp.RequestCtx) {
	ip := helper.FromRequest(ctx)
	admin_info := session.AdminGet(ctx)
	opt_id, _ := strconv.Atoi(admin_info["id"])
	InsertOptLog(1, opt_id, name, string(ctx.Path()), string(ctx.PostBody()), ip)
}

func ExportExcel(filename string, title []string, data [][]interface{}) error {
	// 创建一个新的 Excel 文件
	file := excelize.NewFile()
	// 设置工作表的名称
	sheetName := "Sheet1"
	// 在工作表中写入标题
	for col, value := range title {
		cell := excelize.ToAlphaString(col) + "1"
		file.SetCellValue(sheetName, cell, value)
	}
	// 在工作表中写入数据
	for row, rowData := range data {
		for col, value := range rowData {
			cell := excelize.ToAlphaString(col) + fmt.Sprint(row+2)
			file.SetCellValue(sheetName, cell, value)
		}
	}
	saveName := "excel/" + filename + ".xlsx"
	//保存文件
	if err := file.SaveAs(saveName); err != nil {
		return err
	} else {
		return nil
	}

}

func DownloadExcel(filename string, ctx *fasthttp.RequestCtx) error {
	// 创建一个新的 Excel 文件
	file, err := excelize.OpenFile("excel/" + filename + ".xlsx")
	if err != nil {
		return err
	}
	ctx.Response.Header.Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename+".xlsx"))
	ctx.Response.Header.Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
	ctx.Response.Header.Set("Content-Transfer-Encoding", "binary")
	ctx.Response.Header.Set("Cache-Control", "must-revalidate")
	ctx.Response.Header.Set("Pragma", "public")
	buffer, err := file.WriteToBuffer()
	if err != nil {
		ctx.Write([]byte("导出失败, " + err.Error()))
		return nil
	}
	ctx.Write(buffer.Bytes())
	return nil
}

// json请求
func HttpJsonRequest(url string, method string, data interface{}) ([]byte, error) {
	jsonData, err := helper.JsonMarshal(data)
	if err != nil {
		return nil, err
	}
	req, err := http.NewRequest(method, url, bytes.NewBuffer(jsonData))
	if err != nil {
		return nil, err
	}
	req.Header.Set("Content-Type", "application/json")
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	// 读取响应体
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	return body, nil
}

func HttpPostHeader(requestBody []byte, requestURI string, headers map[string]string) (int, []byte, error) {

	req := fasthttp.AcquireRequest()
	resp := fasthttp.AcquireResponse()

	defer func() {
		fasthttp.ReleaseResponse(resp)
		fasthttp.ReleaseRequest(req)
	}()

	req.SetRequestURI(requestURI)
	req.Header.SetMethod("POST")
	req.SetBody(requestBody)

	//req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	if headers != nil {
		for k, v := range headers {
			req.Header.Set(k, v)
		}
	}

	err := fc.DoTimeout(req, resp, apiTimeOut)
	return resp.StatusCode(), resp.Body(), err
}

func RemoveWithPrefix(input, prefix string) string {
	parts := strings.Split(input, ",")
	var nonEightyParts []string

	// 遍历切片
	for _, part := range parts {
		// 跳过空字符串和以"80"开头的字符串
		if part != "" && !strings.HasPrefix(part, prefix) {
			nonEightyParts = append(nonEightyParts, part)
		}
	}
	return strings.Join(nonEightyParts, ",")
}

func AddWithPrefix(input, prefix string) string {
	data := []string{}
	query := "select id from tbl_admin_priv where state=1 and pid=" + prefix + " order by sortlevel asc"

	meta.MerchantDB.Select(&data, query)
	data = append(data, prefix)
	return input + "," + strings.Join(data, ",")
}

func GetRandId(digit int) string {
	rand.New(rand.NewSource(time.Now().UnixNano()))
	newId := strconv.Itoa(rand.Intn(int(math.Pow(10, float64(digit)))))
	if len(newId) != digit {
		return GetRandId(digit)
	} else {
		return newId
	}
}

// 批量更新
func BatchUpdate(uids []string, table, str, value string) error {
	// 创建 Redis 管道
	pipe := meta.MerchantRedis.Pipeline()
	defer pipe.Close()

	for _, uid := range uids {
		hashKey := fmt.Sprintf("UserId:%s", uid)
		field := table + ":" + str
		// 将每个 HSET 命令添加到 Pipeline
		pipe.HSet(ctx, hashKey, field, value)
	}

	// 执行 Pipeline
	_, err := pipe.Exec(ctx)
	if err != nil {
		fmt.Printf("Failed to execute pipeline: %v\n", err)
		return err
	}

	fmt.Println("Successfully executed batch HSET")
	return nil
}
